package com.yzy.soft.system.freemarker;


import com.alibaba.fastjson.JSONObject;
import com.yzy.soft.system.freemarker.database.Column;
import com.yzy.soft.system.freemarker.database.PrimaryKey;
import com.yzy.soft.system.freemarker.database.Table;
import freemarker.template.Template;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.*;



public class TestCodeGenerateUtils2 {
    private static Logger logger= LoggerFactory.getLogger(TestCodeGenerateUtils2.class);
    private JavaFile fileInfo;
    private DBInfo dbInfo;
    private final String tableName = "tm_project_quality_problem";

    public JavaFile getfileInfo() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
        Calendar calendar = Calendar.getInstance();
        fileInfo = new JavaFile();
        fileInfo.setAuthor("Yinzhiyuan");
        fileInfo.setCreateTime(format.format(calendar.getTime()));
        fileInfo.setEncoding("UTF-8");
        fileInfo.setPackageName("com.yzy.soft.system");
        fileInfo.setDiskPath("D:\\BaiduYunDownload\\liscw-parent\\CodeBuilder\\src\\main\\");
        return fileInfo;
    }

    public DBInfo getDbInfo() {
        dbInfo = new DBInfo();
        dbInfo.setDriver("com.mysql.jdbc.Driver");
        dbInfo.setUrl("jdbc:mysql://127.0.0.1:3307/codebuilder?characterEncoding=utf8&useSSL=false");
        dbInfo.setUsername("root");
        dbInfo.setPassword("root");
        return dbInfo;
    }

//    private final static String diskPath = "D:\\BaiduYunDownload\\liscw-parent\\IFI\\src\\main\\java";
//    private final String changeTableName = replaceUnderLineAndUpperCase(tableName);

    public Connection getConnection() throws Exception {
        Class.forName(dbInfo.getDriver());
        Connection connection = DriverManager.getConnection(dbInfo.getUrl(), dbInfo.getUsername(), dbInfo.getPassword());
        return connection;
    }

    //基础信息

//    private final static String[] upperTableName=new String[]{"Baseinfo", "Faq", "Navbarinfo", "Price", "Priceversion", "Priceversionfeature", "Productionfeature", "Productioninfo", "Productionshow"};
//    private final static String[] lowerTableName=new String[]{"baseinfo", "faq", "navbarinfo", "price", "priceversion", "priceversionfeature", "productionfeature", "productioninfo", "productionshow"};

    private String[] upperTableName = new String[]{"Test"};
    private String[] lowerTableName = new String[]{"test"};
    //项目相关
//    private final static String project_name = "codeBuilder";
    private final static String project_name = "soft";

    //controller相关
    private final static String path_controller = "//com//yzy//soft//system//controller//";

    private final static String[] tableAnnotation = new String[]{"业务交易模板"};
    private String[] controllerFileName = upperTableName;
    private final static String[] class_remark = new String[]{};
    private String[] class_requestMapping = lowerTableName;


    //mapper接口相关
    private String[] mapperName = upperTableName;
    private final String path_mapper = "//com//yzy//soft//common//persistence//dao//";
    private String[] mapper_tablename = upperTableName;
    private final String mapper_packageName = "com.yzy.soft.common.persistence.dao";

    //mapperXML文件相关
    private String[] mapperXMLName = upperTableName;
    private final String path_mapperXML = "//com//yzy//soft//common//persistence//dao//mapping//";
    private String[] mapperXML_tablename = upperTableName;
    private final String mapperXML_packageName = "com.yzy.soft.common.persistence.dao";

    //Dto相关
    private final String path_dto = "//com//yzy//soft//system//dto//";
    private String[] dto_tablename = upperTableName;
    private final String dto_packageName = "com.yzy.soft.system.dto";

    public TestCodeGenerateUtils2() {

    }

    public TestCodeGenerateUtils2(String[] upperTableName, String[] lowerTableName) {
        this.upperTableName = upperTableName;
        this.lowerTableName = lowerTableName;
        this.controllerFileName = upperTableName;
        this.class_requestMapping = lowerTableName;
        this.mapperName = upperTableName;
        this.mapper_tablename = upperTableName;
        this.mapperXMLName = upperTableName;
        this.mapperXML_tablename = upperTableName;
        this.dto_tablename = upperTableName;
    }


    public static void main(String[] args) throws Exception {
        TestCodeGenerateUtils2 testCodeGenerateUtils = new TestCodeGenerateUtils2();
        testCodeGenerateUtils.getfileInfo();
        testCodeGenerateUtils.getDbInfo();
        testCodeGenerateUtils.generate();
        logger.info("info: {}","22222222222222");
        System.out.println("2222222222222222222222222");
    }

    public void generate() throws Exception {
        try {
            List<String> sss = new ArrayList<>();
//            sss.add("Controller");
//            sss.add("Mapper");
//            sss.add("MapperXML");
            sss.add("Model");
////            sss.add("DTO");
            for (int i = 0; i < sss.size(); i++) {
                //生成Controller控制层文件
                if (("Controller").equals(sss.get(i))) {
                    generateControllerFile();
                } else if (("Mapper").equals(sss.get(i))) {
                    //生成Mapper接口文件
                    generateMapperFile();
                } else if (("MapperXML").equals(sss.get(i))) {
                    //生成MapperXML配置文件
                    generateMapperXMLFile();
                } else if (("Model").equals(sss.get(i))) {
                    JdbcUtil jdbcUtil=new JdbcUtil(dbInfo.getDriver(),dbInfo.getUrl(),dbInfo.getUsername(),dbInfo.getPassword());
                    List<Table> tablesList = jdbcUtil.getTablesList();
                    for (int j = 0; j < tablesList.size(); j++) {
                        Table table =tablesList.get(j);
                        List<Column> columnsInfo = jdbcUtil.getColumnsInfoByTable(table.getTableName());
                        table.setColumns(columnsInfo);

                        List<PrimaryKey> primaryKeysInfo=jdbcUtil.getPrimaryKeysInfoByTable(table.getTableName());
                        table.setPrimaryKeys(primaryKeysInfo);
                    }
                    //生成Model配置文件


                    for (int j = 0; j <tablesList.size() ; j++) {
                        generateModelFile(tablesList.get(j));
                    }


                } else if (("DTO").equals(sss.get(i))) {
                    //生成DTO数据传输对象文件
                    generateDTOFile();
                }
//                } else if (("Dao").equals(sss.get(i))) {
//                    generateDaoFile(resultSet);
//                } else if (("Controller").equals(sss.get(i))) {
//                    generateServiceInterfaceFile(resultSet);
//                } else if (("Controller").equals(sss.get(i))) {
//                    generateServiceImplFile(resultSet);
//                }
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {

        }
    }


    private void generateControllerFile() throws Exception {
        final String suffix = "Controller.java";
        final String templateName = "Controller.ftl";
        File file = new File(fileInfo.getDiskPath() + path_controller);
        if (!file.exists()) {
            file.createNewFile();
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("dto_packageName", dto_packageName);
        for (int i = 0; i < dto_tablename.length; i++) {
//            dataMap.put("dto_tablename",dto_tablename[i]);
            dataMap.put("table_annotation", tableAnnotation[0]);
            dataMap.put("class_requestMapping", class_requestMapping[i]);
            dataMap.put("table_name", controllerFileName[i]);
            String path = fileInfo.getDiskPath() + path_controller + controllerFileName[i] + suffix;
            File controllerFile = new File(path);
            generateFileByTemplate(templateName, controllerFile, dataMap);
        }
    }

    private void generateModelFile(Table table) throws Exception {
        logger.info("info: {}",table);
        final String suffix = ".java";

//        String tableName1=table.getTableName().toUpperCase().substring(0,1);
//        tableName1=tableName1+table.getTableName().substring(1);
        String tableName1 = replaceUnderLineAndUpperCase(table.getTableName());
        final String path = fileInfo.getDiskPath() + tableName1 + suffix;

        final String templateName = "Model.ftl";
        File mapperFile = new File(path);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("model_column", table.getColumns());
        dataMap.put("table_name", tableName1);
        generateModelByTemplate(templateName, mapperFile, dataMap);

    }

    //
    private void generateDTOFile() throws Exception {
        final String suffix = "Dto.java";
        final String templateName = "DTO.ftl";
        File file = new File(fileInfo.getDiskPath() + path_dto);
        if (!file.exists()) {
            file.createNewFile();
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("dto_packageName", dto_packageName);
        for (int i = 0; i < dto_tablename.length; i++) {
            dataMap.put("dto_tablename", dto_tablename[i]);

            String path = fileInfo.getDiskPath() + path_dto + dto_tablename[i] + suffix;
            File dtoFile = new File(path);
            generateFileByTemplate(templateName, dtoFile, dataMap);
        }
    }


    //
//    
//
    private void generateServiceImplFile(ResultSet resultSet) throws Exception {
        final String suffix = "ServiceImpl.java";
        final String path = fileInfo.getDiskPath() + upperTableName + suffix;
        final String templateName = "ServiceImpl.ftl";
        File mapperFile = new File(path);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    //
    private void generateServiceInterfaceFile(ResultSet resultSet) throws Exception {
        final String prefix = "I";
        final String suffix = "Service.java";
        final String path = fileInfo.getDiskPath() + prefix + upperTableName + suffix;
        final String templateName = "ServiceInterface.ftl";
        File mapperFile = new File(path);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    //
    private void generateRepositoryFile(ResultSet resultSet) throws Exception {
        final String suffix = "Repository.java";
        final String path = fileInfo.getDiskPath() + upperTableName + suffix;
        final String templateName = "Repository.ftl";
        File mapperFile = new File(path);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    private void generateDaoFile(ResultSet resultSet) throws Exception {
        final String suffix = "DAO.java";
        final String path = fileInfo.getDiskPath() + upperTableName + suffix;
        final String templateName = "DAO.ftl";
        File mapperFile = new File(path);
        Map<String, Object> dataMap = new HashMap<String, Object>();
        generateFileByTemplate(templateName, mapperFile, dataMap);
    }

    //
    private void generateMapperFile() throws Exception {
        final String suffix = "Mapper.java";
//        final String path = diskPath + path_mapper+mapperName + suffix;
        final String templateName = "Mapper.ftl";
        File file = new File(fileInfo.getDiskPath() + path_mapper);
        if (!file.exists()) {
            file.createNewFile();
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        for (int i = 0; i < mapperName.length; i++) {
            dataMap.put("mapper_tablename", mapper_tablename[i]);
            dataMap.put("mapper_packageName", mapper_packageName);

            String path = fileInfo.getDiskPath() + path_mapper + mapperName[i] + suffix;
            File mapperFile = new File(path);

            generateFileByTemplate(templateName, mapperFile, dataMap);
        }


    }

    private void generateMapperXMLFile() throws Exception {
        final String suffix = "Mapper.xml";
//        final String path = diskPath + path_mapper+mapperName + suffix;
        final String templateName = "MapperXML.ftl";
        File file = new File(fileInfo.getDiskPath() + path_mapperXML);
        if (!file.exists()) {
            file.createNewFile();
        }
        Map<String, Object> dataMap = new HashMap<String, Object>();
        for (int i = 0; i < mapperXMLName.length; i++) {
            dataMap.put("mapperXML_tablename", mapperXML_tablename[i]);
            dataMap.put("mapperXML_packageName", mapperXML_packageName);
            String path = fileInfo.getDiskPath() + path_mapperXML + mapperXMLName[i] + suffix;
            File mapperFile = new File(path);
            generateFileByTemplate(templateName, mapperFile, dataMap);
        }
    }

    //
    private void generateFileByTemplate(final String templateName, File file, Map<String, Object> dataMap) throws Exception {
        if (file.exists()) {
            file.deleteOnExit();
        }
        Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
        FileOutputStream fos = new FileOutputStream(file);
        dataMap.put("table_name_small", tableName);

        dataMap.put("author", fileInfo.getAuthor());
        dataMap.put("date", fileInfo.getCreateTime());
        dataMap.put("package_name", fileInfo.getPackageName());

        dataMap.put("project_name", project_name);


        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240);
        template.process(dataMap, out);
    }

    private void generateModelByTemplate(final String templateName, File file, Map<String, Object> dataMap) throws Exception {
        if (file.exists()) {
            file.deleteOnExit();
        }
        Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
        FileOutputStream fos = new FileOutputStream(file);
        dataMap.put("table_name_small", upperTableName);
//     dataMap.put("table_name", tableName);
        dataMap.put("author", fileInfo.getAuthor());
        dataMap.put("date", fileInfo.getCreateTime());
        dataMap.put("package_name", fileInfo.getPackageName());

        dataMap.put("project_name", project_name);


        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240);
        template.process(dataMap, out);
    }

    //
    public String replaceUnderLineAndUpperCase(String str) {
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while (count != 0) {
            int num = sb.indexOf("_", count);
            count = num + 1;
            if (num != -1) {
                char ss = sb.charAt(count);
                char ia = (char) (ss - 32);
                sb.replace(count, count + 1, ia + "");
            }
        }
        String result = sb.toString().replaceAll("_", "");
        return StringUtils.capitalize(result);
    }

}
 

